package com.hxzy.controller.anonymous.sms;

import com.hxzy.common.annotates.RateLimiter;
import com.hxzy.common.constants.MarketConstants;
import com.hxzy.common.constants.RedisConstants;
import com.hxzy.common.enums.AckCode;
import com.hxzy.common.enums.LimitType;
import com.hxzy.common.exception.ServiceException;
import com.hxzy.common.resp.R;
import com.hxzy.controller.anonymous.sms.req.MobileReq;
import com.hxzy.controller.anonymous.sms.req.ValidatorCodeReq;
import com.hxzy.controller.anonymous.sms.resp.MobileResp;
import com.hxzy.service.MerchandiserService;
import com.hxzy.service.SmsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping(value = "/anony/sms")
@Api(tags = "匿名-发送短信Api")
public class AnonySmsController {


    //@Qualifier(value = "tencentSmsServiceImpl")
    @Autowired
    private SmsService smsService;

    @Autowired
    private MerchandiserService merchandiserService;

    @Autowired
    private RedisTemplate redisTemplate;

    @RateLimiter(time = 60,count = 1,limitType = LimitType.IP)
    @ApiOperation(value = "获取短信验证码")
    @PostMapping(value = "/getCode")
    public R<MobileResp>   smsVerificationCode(@RequestBody @Valid MobileReq req){
        //限制某一个IP，在某一段时间，调用这个接口的次数

        //验证账号是否被使用过了
        long count=this.merchandiserService.existsAccount(req.getMobile());
        if(count>0){
            throw new ServiceException(AckCode.EXISTS_VALUE_ACCOUNT);
        }

        String redisKey= RedisConstants.SMS_TOKEN_PREFIX+req.getMobile();
        //先判断缓存中是否存在验证码
        if(this.redisTemplate.hasKey(redisKey)){
            throw new ServiceException(AckCode.SMS_CODE_NOT_EXPIRED);
        }

        //{1}为您的登录验证码，请于{2}分钟内填写，如非本人操作，请忽略本短信。
        String code= this.smsService.generateCode(4);
        String[] params={code, RedisConstants.SMS_EXPIRED_MINUTES.toString()};
        //发送短信
        boolean result=this.smsService.sendCodeSms(req.getMobile(),params);
        //短信发送失败
        if(!result){
            throw new ServiceException(AckCode.SMS_SEND_FAILED);

        }
        //存储到redis中
        this.redisTemplate.opsForValue().set(redisKey,code,RedisConstants.SMS_EXPIRED_MINUTES, TimeUnit.MINUTES);

        //把数据发给前端
        MobileResp resp=new MobileResp();
        resp.setUuid(req.getMobile());
        resp.setSeconds(RedisConstants.SMS_EXPIRED_MINUTES*60);

        return R.okHasData(resp);
    }

    @ApiOperation(value = "验证手机验证码")
    @PostMapping(value = "/validate/code")
    public R validateRegisterCode(@RequestBody @Valid ValidatorCodeReq req){
        //验证账号是否被使用过了
        long count=this.merchandiserService.existsAccount(req.getMobile());
        if(count>0){
            throw new ServiceException(AckCode.EXISTS_VALUE_ACCOUNT);
        }

        String redisKey= RedisConstants.SMS_TOKEN_PREFIX+req.getMobile();
        //先判断缓存中是否存在验证码
        Object redisValue = this.redisTemplate.opsForValue().get(redisKey);
        if(Objects.isNull(redisValue)){
            throw new ServiceException(AckCode.CODE_NOT_FOUND);
        }

        if(!redisValue.toString().equalsIgnoreCase(req.getCode())){
            throw new ServiceException(AckCode.CODE_ERROR);
        }

        //删除验证码
        this.redisTemplate.delete(redisKey);

        return R.ok();
    }


}
